package com.lengyu.iottransfer.gateway.influxdb.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import com.lengyu.iottransfer.gateway.common.BasePageParamDto;
import com.lengyu.iottransfer.gateway.influxdb.InfluxdbService;
import com.lengyu.iottransfer.gateway.influxdb.dto.DeviceLogDto;
import com.lengyu.iottransfer.gateway.influxdb.dto.QueryDataDto;
import com.lengyu.iottransfer.gateway.influxdb.dto.QueryFieldDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DeviceLogInfluxService {
    private final static Logger logger = LoggerFactory.getLogger(DeviceLogInfluxService.class);

    @Autowired
    InfluxdbService influxdbService;


    public Page<DeviceLogDto> page(BasePageParamDto pageParamDto){
        Page<DeviceLogDto> result = new Page<>();
        JSONObject paramJson = pageParamDto.getParamMapObj();
        String deviceCode = paramJson.getString("deviceCode");
        String msgType = paramJson.getString("msgType");

        StringBuilder querySb = new StringBuilder();
        if(StringUtils.isNotBlank(deviceCode)){
            querySb.append(influxdbService.queryParamStr("=",deviceCode,"devicecode"));
        }
        if(StringUtils.isNotBlank(msgType)){
            querySb.append( influxdbService.queryParamStr("=",msgType,"msgtype"));
        }
        List<Long> timeList = (ArrayList)paramJson.get("time");

        if(timeList == null || timeList.size() != 2){
            return null;
        }
        String queryStr = querySb.toString();
        int pageIndex = pageParamDto.getPageIndex();
        int pageSize = pageParamDto.getPageSize();
        Long totalCount = influxdbService.totalCount(timeList.get(0),
                timeList.get(1),"device_log",
                "iot_transfer_log",queryStr,false);
        if(totalCount > 0){

            if(pageSize == 0){
                pageSize = 10;
            }

            if(totalCount < pageSize*(pageIndex)){
                //如果总数小于上一页的数量，pageIndex切换到最后一页
                if(totalCount%pageSize == 0){
                    pageIndex =((Long)((totalCount/pageSize))).intValue();
                }
                else{
                    pageIndex =((Long)(totalCount/pageSize)).intValue();
                }
            }

            List<FluxTable> tableList = influxdbService.queryListOrderByGroup(System.currentTimeMillis()-(1000*60*60*24),System.currentTimeMillis(),"device_log",
                    "devicecode","iot_transfer_log",pageSize*pageIndex,pageSize,queryStr,false);

            List<DeviceLogDto> deviceLogDtoList = new ArrayList<>();
            if(tableList != null && tableList.size() > 0){
                for (FluxTable table : tableList) {
                    if(table.getRecords() != null && table.getRecords().size() > 0){

                        for (FluxRecord record : table.getRecords()) {
                            DeviceLogDto DeviceLogDto = convertFluxRecordToDeviceLogDto(record);
                            deviceLogDtoList.add(DeviceLogDto);
                        }
                    }
                }
            }

            result.setTotal(totalCount);
            result.setRecords(deviceLogDtoList);
            result.setCurrent(pageIndex);
            result.setSize(pageSize);
            logger.info(JSONObject.toJSONString(result));
        }
        else{

            result.setTotal(0);
            result.setRecords(null);
            result.setCurrent(pageIndex);
            result.setSize(pageSize);
            logger.info(JSONObject.toJSONString(result));
        }
        return result;
    }
    /**
     * convert检索返回信息为设备属性值
     * @param record
     * @return
     */
    private DeviceLogDto convertFluxRecordToDeviceLogDto(FluxRecord record){
        DeviceLogDto devicePropertyRowDto = new DeviceLogDto();
        devicePropertyRowDto.setTime(new Date(record.getTime().toEpochMilli()));
        //
        devicePropertyRowDto.setTimeStamp(record.getTime().toEpochMilli());
        devicePropertyRowDto.setSeconds(record.getTime().getEpochSecond());
        devicePropertyRowDto.setNanoSeconds(record.getTime().getNano());

        for(String key:record.getValues().keySet()){
            if(key.equals("devicecode")) {
                devicePropertyRowDto.setDeviceCode(String.valueOf(record.getValueByKey("devicecode")));
            }
            else if(key.equals("msgtype")){
                devicePropertyRowDto.setMsgType(String.valueOf(record.getValueByKey("msgtype")));
            }
            else if(key.equals("msg")){
                devicePropertyRowDto.setMsg(String.valueOf(record.getValueByKey("msg")));
            }
        }
        return devicePropertyRowDto;
    }
    /**
     * 增加设备信息记录
     * @param deviceCode  设备编码
     * @param time       属性上报时间
     */
    public void addDeviceLog(String deviceCode, String msg,String msgType, long time,int nanoSecond) {
        QueryDataDto dataDto = new QueryDataDto();
        dataDto.setTableName("iot_transfer_log");
        List<QueryFieldDto> fieldDtoList = new ArrayList<>();

        QueryFieldDto deviceCodeField = new QueryFieldDto();
        deviceCodeField.setKey("deviceCode");
        deviceCodeField.setValueType("string");
        deviceCodeField.setTagFlag(true);
        deviceCodeField.setValue(deviceCode);
        fieldDtoList.add(deviceCodeField);

        QueryFieldDto msgField = new QueryFieldDto();
        msgField.setKey("msg");
        msgField.setValueType("string");
        msgField.setValue(msg);
        fieldDtoList.add(msgField);

        QueryFieldDto msgTypeField = new QueryFieldDto();
        msgTypeField.setKey("msgType");
        msgTypeField.setValueType("string");
        msgTypeField.setValue(msgType);
        msgTypeField.setTagFlag(true);
        fieldDtoList.add(msgTypeField);

        dataDto.setFieldDtoList(fieldDtoList);
        influxdbService.save(dataDto,"device_log",time,nanoSecond);
    }



}
